﻿using System;
using System.Collections;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ctsu.Admin.Forms;
using ctsu.BaseForms;
using ctsu.Data;
using ctsu.Security;

using Syncfusion.Windows.Forms.Tools;

namespace ctsu.Admin.BusLogic
{
	class BLFormAdditionalRoomUsage : BLFormBaseImpl
	{
		enum TimeDirection { In, Out };
		enum RoomNumber { One, Two };

		#region control references
		private DateTimePickerAdv _visitDate;

		protected CheckBox _chkProtocolNA;
		protected Button _btnProtocol;
		protected TextBox _protocol;
		//protected TextBox _spid;
		protected TextBox _protocolNumber;
		protected TextBox _investigator;
		protected TextBox _title;
		protected TextBox _reason;
		protected TextBox _reasonOther;

		protected RadioButton _rdoReason1;
		protected RadioButton _rdoReason2;
		protected RadioButton _rdoReason3;
		protected RadioButton _rdoReason4;

		protected ComboBox _room1;
		protected MaskedTextBox _rm1TimeIn;
		protected MaskedTextBox _rm1TimeOut;
		protected ComboBox _room2;
		protected MaskedTextBox _rm2TimeIn;
		protected MaskedTextBox _rm2TimeOut;
		protected TextBox _rm1Duration;
		protected TextBox _rm2Duration;


		#endregion control references

		public BLFormAdditionalRoomUsage(FormMain formMain, FormBase form, FormInfoBase formInfo, DataTable tableSchema, Permission formSecurity, Hashtable configData)
			: base(formMain, form, formInfo, tableSchema, formSecurity, configData)
		{

		}

		protected override void _vcManager_OnAfterHookEvents()
		{
			_chkProtocolNA = (CheckBox)Forms.Utils.GetControlByName("chkProtocolNA", this._form.Controls);
			_visitDate = (DateTimePickerAdv)Forms.Utils.GetControlByName("VisitDate", this._form.Controls);
			_btnProtocol = (Button)Forms.Utils.GetControlByName("btnProtocol", this._form.Controls);
			_protocol = (TextBox)Forms.Utils.GetControlByName("Protocol", this._form.Controls);
			//_spid = (TextBox)Forms.Utils.GetControlByName("SPID", this._form.Controls);
			_protocolNumber = (TextBox)Forms.Utils.GetControlByName("ProtocolNumber", this._form.Controls);
			_investigator = (TextBox)Forms.Utils.GetControlByName("Investigator", this._form.Controls);
			_title = (TextBox)Forms.Utils.GetControlByName("Title", this._form.Controls);
			_reason = (TextBox)Forms.Utils.GetControlByName("Reason", this._form.Controls);
			_reasonOther = (TextBox)Forms.Utils.GetControlByName("ReasonOther", this._form.Controls);

			_room1 = (ComboBox)Forms.Utils.GetControlByName("Room1", this._form.Controls);
			_rm1TimeIn = (MaskedTextBox)Forms.Utils.GetControlByName("Rm1TimeIn", this._form.Controls);
			_rm1TimeOut = (MaskedTextBox)Forms.Utils.GetControlByName("Rm1TimeOut", this._form.Controls);
			_room2 = (ComboBox)Forms.Utils.GetControlByName("Room2", this._form.Controls);
			_rm2TimeIn = (MaskedTextBox)Forms.Utils.GetControlByName("Rm2TimeIn", this._form.Controls);
			_rm2TimeOut = (MaskedTextBox)Forms.Utils.GetControlByName("Rm2TimeOut", this._form.Controls);
			_rm1Duration = (TextBox)Forms.Utils.GetControlByName("rm1Duration", this._form.Controls);
			_rm2Duration = (TextBox)Forms.Utils.GetControlByName("rm2Duration", this._form.Controls);
			_rdoReason1 = (RadioButton)Forms.Utils.GetControlByName("rdoReason1", this._form.Controls);
			_rdoReason2 = (RadioButton)Forms.Utils.GetControlByName("rdoReason2", this._form.Controls);
			_rdoReason3 = (RadioButton)Forms.Utils.GetControlByName("rdoReason3", this._form.Controls);
			_rdoReason4 = (RadioButton)Forms.Utils.GetControlByName("rdoReason4", this._form.Controls);

			_rm1TimeIn.TextChanged += new EventHandler(_rmTime_TextChanged);
			_rm1TimeOut.TextChanged += new EventHandler(_rmTime_TextChanged);
			_rm2TimeIn.TextChanged += new EventHandler(_rmTime_TextChanged);
			_rm2TimeOut.TextChanged += new EventHandler(_rmTime_TextChanged);
			_room1.SelectionChangeCommitted += new EventHandler(_room1_SelectionChangeCommitted);
			_room2.SelectionChangeCommitted += new EventHandler(_room2_SelectionChangeCommitted);
			_chkProtocolNA.CheckedChanged += new EventHandler(_chkProtocolNA_CheckedChanged);
			_rdoReason1.CheckedChanged += new EventHandler(_rdoReason_CheckedChanged);
			_rdoReason2.CheckedChanged += new EventHandler(_rdoReason_CheckedChanged);
			_rdoReason3.CheckedChanged += new EventHandler(_rdoReason_CheckedChanged);
			_rdoReason4.CheckedChanged += new EventHandler(_rdoReason_CheckedChanged);

			base._vcManager_OnAfterHookEvents();
		}

		protected override void SetControlsEnabled(bool enable)
		{
			base.SetControlsEnabled(enable);
			_btnProtocol.Enabled = enable;
			//_spid.Enabled = enable;
			_protocolNumber.Enabled = enable;
			_investigator.Enabled = enable;
			_title.Enabled = enable;

			_chkProtocolNA.Enabled = enable;
			_rdoReason1.Enabled = enable;
			_rdoReason2.Enabled = enable;
			_rdoReason3.Enabled = enable;
			_rdoReason4.Enabled = enable;
			_rm1Duration.Enabled = enable;
			_rm2Duration.Enabled = enable;

			if (enable)
			{
				int selVal = 0;
				if (_room1.SelectedValue != null)
					selVal = (int)_room1.SelectedValue;
				if (selVal > 1)
				{
					_rm1TimeIn.Enabled = true;
					_rm1TimeOut.Enabled = true;
					_room2.Enabled = true;
				}
				else
				{
					_rm1TimeIn.Enabled = false;
					_rm1TimeOut.Enabled = false;
					_room2.Enabled = false;
				}

				selVal = 0;
				if (_room2.SelectedValue != null)
					selVal = (int)_room2.SelectedValue;
				if (selVal > 1)
				{
					_rm2TimeIn.Enabled = true;
					_rm2TimeOut.Enabled = true;
				}
				else
				{
					_rm2TimeIn.Enabled = false;
					_rm2TimeOut.Enabled = false;
				}

				if (_reason.Text == "4")
					_reasonOther.Enabled = true;
				else
					_reasonOther.Enabled = false;
			}

		}

		void _rdoReason_CheckedChanged(object sender, EventArgs e)
		{
			RadioButton rdo = (RadioButton)sender;
			string num = rdo.Name.Substring(rdo.Name.Length - 1);
			_reason.Text = num;

			_reasonOther.Enabled = false;
			if (num == "4")
				_reasonOther.Enabled = true;
		}

		void _chkProtocolNA_CheckedChanged(object sender, EventArgs e)
		{
			if (_chkProtocolNA.Checked)
			{
				_btnProtocol.Enabled = false;
				ClearProtocolControls();
				_protocol.Text = "0";
			}
			else
			{
				_protocol.Text = "";
				_btnProtocol.Enabled = true;
			}
		}

		protected override void ClearAllControls()
		{
			base.ClearAllControls();
			ClearProtocolControls();
			_chkProtocolNA.Checked = false;
			_rdoReason1.Checked = false;
			_rdoReason2.Checked = false;
			_rdoReason3.Checked = false;
			_rdoReason4.Checked = false;
			_rm1Duration.Text = "";
			_rm1TimeIn.Text = "";
			_rm1TimeOut.Text = "";
			_rm2Duration.Text = "";
			_rm2TimeIn.Text = "";
			_rm2TimeOut.Text = "";
		}

		private void ClearProtocolControls()
		{
			_protocol.Text = "";
			//_spid.Text = "";
			_protocolNumber.Text = "";
			_investigator.Text = "";
			_title.Text = "";
		}

		void _room1_SelectionChangeCommitted(object sender, EventArgs e)
		{
			int selVal = 0;
			if (_room1.SelectedValue != null)
				selVal = (int)_room1.SelectedValue;
			if (selVal > 1)
			{
				_rm1TimeIn.Enabled = true;
				_rm1TimeOut.Enabled = true;
				_room2.Enabled = true;
			}
			else
			{
				_rm1TimeIn.Enabled = false;
				_rm1TimeIn.Text = "__:__";
				_rm1TimeOut.Enabled = false;
				_rm1TimeOut.Text = "__:__";
				_room2.SelectedIndex = 0;
				_room2.Enabled = false;
			}
		}

		void _room2_SelectionChangeCommitted(object sender, EventArgs e)
		{
			int selVal = 0;
			if (_room2.SelectedValue != null)
				selVal = (int)_room2.SelectedValue;
			if (selVal > 1)
			{
				_rm2TimeIn.Enabled = true;
				_rm2TimeOut.Enabled = true;
			}
			else
			{
				_rm2TimeIn.Enabled = false;
				_rm2TimeIn.Text = "__:__";
				_rm2TimeOut.Enabled = false;
				_rm2TimeOut.Text = "__:__";
			}
		}

		void _rmTime_TextChanged(object sender, EventArgs e)
		{
			MaskedTextBox mtb = sender as MaskedTextBox;
			RoomNumber room = RoomNumber.One;
			if (mtb.Name.Contains("2"))
				room = RoomNumber.Two;

			int hrs = 0;
			int mins = 0;

			if (mtb.Text.Substring(0, 2).Trim().Length > 0)
				hrs = int.Parse(mtb.Text.Substring(0, 2));

			if (hrs > 23)
			{
				mtb.Text = "23:" + mtb.Text.Substring(3);
				return;
			}

			if (mtb.Text.Substring(3).Trim().Length > 0)
				mins = int.Parse(mtb.Text.Substring(3));

			if (mins > 59)
			{
				mtb.Text = mtb.Text.Substring(0, 3) + "59";
				return;
			}

			CalcRoomDuration(room);
		}

		private void CalcRoomDuration(RoomNumber room)
		{
			TextBox txtDuration = null;
			if (room == RoomNumber.One)
				txtDuration = _rm1Duration;
			else
				txtDuration = _rm2Duration;
			txtDuration.Text = "";

			//time in
			int hrsIn = 0;
			int minsIn = 0;
			bool isValidTime = GetTimeHrsMins(out hrsIn, out minsIn, room, TimeDirection.In);
			if (!isValidTime)
				return;

			//time out
			int hrsOut = 0;
			int minsOut = 0;
			isValidTime = GetTimeHrsMins(out hrsOut, out minsOut, room, TimeDirection.Out);
			if (!isValidTime)
				return;

			int totMins = 0;
			int hrs = hrsOut - hrsIn;
			totMins = hrs * 60 + (minsOut - minsIn);
			txtDuration.Text = totMins.ToString();
		}

		private bool GetTimeHrsMins(out int hrs, out int mins, RoomNumber room, TimeDirection timeDirection)
		{
			hrs = 0;
			mins = 0;
			MaskedTextBox mtb = null;
			switch (room)
			{
				case RoomNumber.One:
					if (timeDirection == TimeDirection.In)
						mtb = _rm1TimeIn;
					else
						mtb = _rm1TimeOut;
					break;
				case RoomNumber.Two:
					if (timeDirection == TimeDirection.In)
						mtb = _rm2TimeIn;
					else
						mtb = _rm2TimeOut;
					break;
			}

			string text = mtb.Text.Trim();
			int pos = text.IndexOf(':');
			if (pos < 1)
				return false;
			//hrs
			string sHrs = text.Substring(0, pos);
			try
			{
				hrs = int.Parse(sHrs);
			}
			catch
			{
				return false;
			}

			//mins
			string sMins = text.Substring(pos + 1);
			try
			{
				mins = int.Parse(sMins);
				return true;
			}
			catch
			{
				return false;
			}
		}

		public override bool Remove()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("Press 'Yes' to confirm the removal of Outpatient Visit ID: " + this._currentPrimaryID.ToString());
			sb.Append(Environment.NewLine);
			sb.Append("or press 'No' to cancel.");
			if (MessageBox.Show(this._form, sb.ToString(), "Confirm Outpatient Visit Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
				return false;

			sb.Remove(0, sb.Length);

			//this is used as a parameter for table grid display
			DbTableChange tableChange = DbTableChange.Update;

			string sql = "DELETE FROM AdditionalRoomUsage WHERE ID=" + this._currentPrimaryID;

			//SqlConnection conn = DataAccess.GetSqlConnection();
			try
			{
				int i = DataAccess.ExecuteNonQuery(CommandType.Text, sql);
				if (i == 1)
				{
					sb.Append("Additional Room Usage ID: " + this._currentPrimaryID.ToString() + " was deleted.");
					this._fcManager.CurrentRow.Delete();
					this.ResetToOriginal();
					MessageBox.Show(this._form, sb.ToString(), "Confirm Additional Room Usage Visit Removal", MessageBoxButtons.OK, MessageBoxIcon.Information);

					BLTableChangeAdvEventArgs args = new BLTableChangeAdvEventArgs(this._formInfo.TableName, tableChange, this._currentPrimaryID - 1);

					this.FireTableChange(args);
				}
				else
				{
					sb.Append("Additional Room Usage ID: " + this._currentPrimaryID.ToString() + " was not deleted.");
					sb.Append(Environment.NewLine);
					sb.Append(Shared.Constants.NotifySupportImmediate);
					MessageBox.Show(this._form, sb.ToString(), "Additional Room Usage Visit Removal", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not delete Additional Room Usage visit!");
				sb.Append(Environment.NewLine);
				if (ex.Message.IndexOf("COLUMN REFERENCE constraint") > 0)
				{
					sb.Append("There is a record in another table (most likely an acillary record)");
					sb.Append(Environment.NewLine);
					sb.Append("that currently references this record!");
				}
				else
					sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Delete Additional Room Usage Visit Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		#region display data
		public override void DisplayData()
		{
			base.DisplayData();

			FieldContext fc = (FieldContext)this._fcManager.Item("Protocol");
			DisplayProtocol(fc);

			switch (_reason.Text)
			{
				case "1":
					_rdoReason1.Checked = true;
					break;
				case "2":
					_rdoReason2.Checked = true;
					break;
				case "3":
					_rdoReason3.Checked = true;
					break;
				case "4":
					_rdoReason4.Checked = true;
					break;
			}
		}

		private void DisplayProtocol(FieldContext fc)
		{
			StringBuilder sb = new StringBuilder();
			if (_fcManager.CurrentRow[fc.Column.ColumnName] is System.DBNull)
			{
				this._protocol.Text = "";
				//this._spid.Text = "";
				this._protocolNumber.Text = "";
				this._investigator.Text = "";
				_title.Text = "";
				return;
			}

			int id = (int)_fcManager.CurrentRow[fc.Column.ColumnName];
			if (id == 0)
			{
				_chkProtocolNA.Checked = true;
				this._protocol.Text = "0";
				//this._spid.Text = "";
				this._protocolNumber.Text = "";
				this._investigator.Text = "";
				_title.Text = "";
				return;
			}

			_chkProtocolNA.Checked = false;
			GetProtocolData(id);
		}
		#endregion display data

		#region select
		public override void GenericClick(Control sender)
		{
			if (sender.Name == "btnProtocol")
				SelectProtocol();
			if (sender.Name == "lnkMilitaryTime")
				System.Diagnostics.Process.Start("http://www.easysurf.cc/cmtime.htm");
		}

		private void SelectProtocol()
		{
			SelectProtocolDlg spd = new SelectProtocolDlg();
			spd.radioButton3.Visible = false;
			spd.radioButton4.Visible = false;
			spd.btnOK.Top = 65;
			spd.Height = 130;
			spd.ShowDialog(this._form);
			if (spd.SearchChoice == 0)
				SelectProtocolStandard();
			else if (spd.SearchChoice == 1)
				SelectProtocolByInvestigator();
		}

		private void SelectProtocolByInvestigator()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Investigator"];

			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.ShowDialog(this._form);
				if (fs.DialogResult == DialogResult.OK)
				{
					int id = fs.SelectedID;
					GetProtocolData(id);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void SelectProtocolStandard()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Protocol"];

			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.ShowDialog(this._form);
				if (fs.DialogResult == DialogResult.OK)
				{
					Console.WriteLine("DialogResult.OK");
					int id = fs.SelectedID;
					GetProtocolData(id);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void GetProtocolData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT p.ID, p.ProtocolNumber, " +
				" p.PCategory, p.PSite, p.PrepTime, " +
				" i.LastName + ', ' + i.FirstName AS Name, p.Title " +
				" FROM Protocol p, ProtocolStaff ps, Investigator i " +
				" WHERE p.ID = " + id +
				" AND ps.ProtocolID = p.ID " +
				" AND (ps.StaffTypeID = 1 OR  ps.StaffTypeID = 4) " +
				" AND i.ID = ps.InvestigatorID";

			//SqlConnection conn = DataAccess.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (reader.Read())
				{
					this._protocol.Text = reader.GetInt32(0).ToString();
					//this._spid.Text = reader.GetInt32(1).ToString();
					this._protocolNumber.Text = reader.GetString(2);
					this._investigator.Text = reader.GetString(6);
					this._title.Text = reader.GetString(7);
				}
				else
				{
					//TODO - do something here
					sb.Append("Could not retrieve protocol data.");
					sb.Append("\nThe most likely cause is that there is no primary investigator selected.");
					sb.Append("\nEdit the protocol and select a primary investigatory(or admitting MD).");
					MessageBox.Show(this._form, sb.ToString(), "Retrieve Protocol Information Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return;
				}
				//GetPatientActualProjectedPercent(id);
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve protocol information!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Protocol Information Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}
		#endregion select

		protected bool VerifyVisitDate(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;

			if (!this.VerifyDate(fc.Control))
			{
				fc.ErrorMessage = "Room usage date is required";
				return false;
			}

			//date must not be greater than today
			DateTime dt = (DateTime)fc.CurrentValue;
			dt = dt.Date;
			if (dt.CompareTo(DateTime.Today) > 0)
			{
				fc.ErrorMessage = "Room usage date can't be greater than today's date";
				return false;
			}
			return true;
		}

		protected bool VerifyProtocol(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;

			if (ctl.Text.Length == 0)
			{
				fc.ErrorMessage = "Select a protocol or select 'Not Applicable'";
				return false;
			}

			return true;
		}

		private bool VerifyRoom1(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;

			int selVal = 0;
			if (_room1.SelectedValue != null)
				selVal = (int)_room1.SelectedValue;

			if (selVal < 2)
			{
				fc.ErrorMessage = "Room1 is required!";
				return false;
			}
			return true;
		}

		private bool VerifyRoomTimes(Control ctl)
		{
			int duration = 0;
			string message = "";

			FieldContext fc = (FieldContext)ctl.Tag;

			//Room 1
			if (ctl.Name == "Rm1TimeIn")
			{
				if (!IsValidRoomTime(RoomNumber.One, out message))
				{
					fc.ErrorMessage = message;
					return false;
				}

				//time out must be greater than time in
				duration = int.Parse(_rm1Duration.Text);
				if (duration <= 0)
				{
					fc.ErrorMessage = "Time out must be greater than time in";
					return false;
				}

				return true;
			}

			//room 2
			int selVal = 0;
			if (_room2.SelectedValue != null)
				selVal = (int)_room2.SelectedValue;

			if (selVal > 1) //time is required
			{
				if (!IsValidRoomTime(RoomNumber.Two, out message))
				{
					fc.ErrorMessage = message;
					return false;
				}

				//time out must be greater than time in
				duration = int.Parse(_rm2Duration.Text);
				if (duration <= 0)
				{
					fc.ErrorMessage = "Time out must be greater than time in";
					return false;
				}
			}
			return true;
		}

		private bool IsValidRoomTime(RoomNumber room, out string message)
		{
			message = "";
			//time in
			int hrsIn = 0;
			int minsIn = 0;
			bool isValidTime = GetTimeHrsMins(out hrsIn, out minsIn, room, TimeDirection.In);
			if (!isValidTime)
			{
				message = "Invalid time";
				return false;
			}

			//time out
			int hrsOut = 0;
			int minsOut = 0;
			isValidTime = GetTimeHrsMins(out hrsOut, out minsOut, room, TimeDirection.Out);
			if (!isValidTime)
			{
				message = "Invalid time";
				return false;
			}

			if (hrsOut < hrsIn)
			{
				message = "Time out must be greater than time in";
				return false;
			}
			if (hrsOut == hrsIn && minsOut < minsIn)
			{
				message = "Time out must be greater than time in";
				return false;
			}

			return true;
		}

		private bool VerifyReason(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;

			if (_reason.Text == "0" || _reason.Text.Length == 0)
			{
				fc.ErrorMessage = "Select a reason!";
				return false;
			}

			return true;
		}

		private bool VerifyReasonOther(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;

			if (_reason.Text == "4")
			{
				if (_reasonOther.Text.Length == 0)
				{
					fc.ErrorMessage = "Enter some text for other reson!";
					return false;
				}
			}
			return true;
		}
	}
}
